package android_serialport_api.utils;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.InvalidParameterException;
import java.util.List;

import android_serialport_api.SerialPort;
import android_serialport_api.bean.ComBean;

public class SerialPortUtil {

	private SerialPortUtil() {
	}

	private static final SerialPortUtil mInstance = new SerialPortUtil();

	public static SerialPortUtil getInstance() {
		return mInstance;
	}

	private SerialPort mSerialPort;
	private OutputStream mOutputStream;
	private InputStream mInputStream;
	private ReadThread mReadThread;
	private Long sleepTime = 40L;
	private String command = "/system/bin/su";
	/* 读取模式 */
	private int readMode;
	/* 读取模式一: 自定义读取间隔休眠时间 10为5毫秒 */
	public static final int READ_SLEEP_MODE = 0;
	/* 读取模式二: 定时读取间隔休眠时间 20毫秒 */
	public static final int READ_END_0D_MODE = 1;
	private boolean isOpen = false;
	private String path = "/dev/ttyS1";
	private int baudrate = 9600;
	private iSerilaPortResult mSerilaPortResult;

	/**
	 * 获取设置的 间隔读取数据休眠时间
	 * 
	 * @return 休眠时间
	 */
	public Long getSleepTime() {
		return this.sleepTime;
	}

	/**
	 * 判断串口是否打开成功
	 * 
	 * @return 串口打开状态
	 */
	public boolean getIsOpen() {
		return this.isOpen;
	}

	/**
	 * 设置 波特率
	 * 
	 * @param baudrate 波特率
	 */
	public void setBaudrate(int baudrate) {
		this.baudrate = baudrate;
	}

	/**
	 * 设置 路径
	 * 
	 * @param path 路径
	 */
	public void setPath(String path) {
		if (!this.isEmpty(path)) {
			this.path = path;
		}

	}

	private void setPermissionCommand(String command) {
		this.command = command;
	}

	/**
	 * 判断对象是否为空
	 * 
	 * @param obj 对象
	 * @return boolean 比对结果
	 */
	private boolean isEmpty(Object obj) {
		if (obj instanceof String) {
			return obj == null || ((String) obj).length() == 0 || "null".equals((String) obj);
		} else if (obj instanceof Object[]) {
			Object[] temp = (Object[]) ((Object[]) obj);

			for (int i = 0; i < temp.length; ++i) {
				if (!this.isEmpty(temp[i])) {
					return false;
				}
			}

			return true;
		} else if (!(obj instanceof List)) {
			return obj == null;
		} else {
			return obj == null || ((List) obj).isEmpty();
		}
	}

	/**
	 * 获取 串口路径
	 * 
	 * @return 路径
	 */
	public String getPath() {
		return this.path;
	}

	public void startSerialPort(int READ_MODE) throws Exception {
		this.startSerialPort(READ_MODE, 40L);
	}

	/**
	 * 开始串口连接，获取串口相关对象，或启动读取串口数据线程
	 * 
	 * @param READ_MODE 模式
	 * @param sleepTime 休眠时间
	 * @throws Exception 异常
	 */
	public void startSerialPort(int READ_MODE, Long sleepTime) throws Exception {
		if (this.mSerialPort == null) {
			this.mSerialPort = new SerialPort(new File(this.path), this.baudrate, 0);
			this.mOutputStream = this.mSerialPort.getOutputStream();
			this.mInputStream = this.mSerialPort.getInputStream();
			if (this.mSerilaPortResult != null) {
				this.readMode = READ_MODE;
				this.sleepTime = sleepTime;
				this.mReadThread = new ReadThread();
				this.mReadThread.start();
			}

			this.isOpen = true;
		}

	}

	/**
	 * 需要读取串口返回内容，设置回调接口接收数据
	 * 
	 * @param mSerilaPortResult 回调接口
	 */
	public void setSerilaPortResult(iSerilaPortResult mSerilaPortResult) {
		this.mSerilaPortResult = mSerilaPortResult;
	}

	/**
	 * 关闭串口相关对象
	 * 
	 * @throws Exception 异常类型
	 */
	public void closeSerialPort() throws Exception {
		if (mInstance != null && this.isOpen) {
			this.isOpen = false;
			if (this.mReadThread != null) {
				this.mReadThread.interrupt();
				this.mReadThread = null;
			}

			if (this.mSerilaPortResult != null) {
				this.mSerilaPortResult = null;
			}

			if (this.mOutputStream != null) {
				this.mOutputStream.close();
			}

			if (this.mInputStream != null) {
				this.mInputStream.close();
			}

			if (this.mSerialPort != null) {
				this.mSerialPort.close();
				this.mSerialPort = null;
			}
		}

	}

	/**
	 * 发送String数据
	 * 
	 * @param writeBytes 发送数据
	 * @return 是否发送成功
	 */
	private boolean sendData(String writeBytes) {
		boolean result = true;
		if (mInstance != null && this.isOpen) {
			byte[] mBuffer = MyFunc.HexToByteArr(writeBytes);
			try {
				if (this.mOutputStream != null) {
					this.mOutputStream.write(mBuffer);
				} else {
					result = false;
				}
			} catch (IOException var5) {
				var5.printStackTrace();
				result = false;
			}
		} else {
			result = false;
		}

		return result;
	}

	/**
	 * 串口读取线程
	 * 
	 * @author face_h
	 *
	 */
	private class ReadThread extends Thread {
		private boolean isOldstart = false;
		private int sum = 0;
		private byte[] read = new byte[1024];
		private int readSize = 0;

		public ReadThread() {
		}

		private void resultData() {
			ComBean ComRecData = new ComBean(SerialPortUtil.this.path, this.read, this.readSize);
			if (SerialPortUtil.this.mSerilaPortResult != null) {
				SerialPortUtil.this.mSerilaPortResult.SerilaPortResult(ComRecData);
			}

			this.readSize = 0;
			this.read = new byte[1024];
		}

		@Override
		public void run() {
			super.run();

			while (!this.isInterrupted()) {
				try {
					if (SerialPortUtil.this.mInputStream == null) {
						return;
					}

					int available = SerialPortUtil.this.mInputStream.available();
					/* Log.e("face serialPortUtil", "available() = " + available); */
					if (available > 0) {
						byte[] buffer = new byte[1024];
						int size = SerialPortUtil.this.mInputStream.read(buffer);
						if (size > 0) {
							for (int i = 0; i < size && this.readSize + i < 1024; ++i) {
								this.read[this.readSize + i] = buffer[i];
							}
							this.readSize += size;
							if (this.readSize >= 1024) {
								this.readSize = 1024;
							}
						}

						this.isOldstart = false;
						this.sum = 3;
					} else {
						if (this.readSize > 0 && /* this.isOldstart */ this.sum == 0) {
							if (SerialPortUtil.this.readMode == 0) {
								this.resultData();
							} else if (SerialPortUtil.this.readMode == 1
									&& "0D".equals(MyFunc.Byte2Hex(this.read[this.readSize - 1]))) {
								--this.readSize;
								this.resultData();
							}
						}

						this.isOldstart = true;
						--this.sum;
					}

				} catch (Throwable var5) {
					var5.printStackTrace();
					return;
				} finally {
					try {
						if (SerialPortUtil.this.readMode == READ_SLEEP_MODE) {
							Thread.sleep((long) ((double) SerialPortUtil.this.sleepTime * 0.5D));
						} else if (SerialPortUtil.this.readMode == READ_END_0D_MODE) {
							Thread.sleep(20L);
						}
					} catch (InterruptedException var4) {
						var4.printStackTrace();
						this.interrupt();
					}
				}
			}

		}
	}

	/**
	 * 串口接口回调返回内容
	 * 
	 * @author face_h
	 *
	 */
	public interface iSerilaPortResult {
		void SerilaPortResult(ComBean var1);
	}
}
